﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Carto;
using PlanningGIS.Util.Management;
using PlanningGIS.Util.Regular;
using PlanningGIS.Win.Controls;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.Symbol
{
    /// <summary>
    /// 作用：拉伸渲染
    /// </summary>
    public partial class RasterStretched : UserControl
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public RasterStretched()
        {
            InitializeComponent();
            m_rasterStretchColorRampRenderer = new RasterStretchColorRampRendererClass();

            cmbColorRamp.Init();

            backgroundColor.ImageVisiable = false;
            backgroundColor.InitStyle();
            
            colorNoData.ImageVisiable = false;
            colorNoData.InitStyle();
        }
        /// <summary>
        /// 
        /// </summary>
        IRasterStretchColorRampRenderer m_rasterStretchColorRampRenderer = null;
        /// <summary>
        /// 
        /// </summary>
        private IRasterLayer m_pRasterLayer;
        /// <summary>
        /// 
        /// </summary>
        public IRasterLayer RasterLayer
        {
            get { return m_pRasterLayer; }
            set
            {
                m_pRasterLayer = value;
                InitStrechFrame();
                
            }
        }

        /// <summary>
        /// 初始化拉伸符号化页面
        /// </summary>
        private void InitStrechFrame()
        {
            if (m_pRasterLayer == null) return;
            InitStrechStyle();
            InitBand();

            #region 初始化最大最小值(就算一开始不是分级渲染，也要有个最大最小值)
            IRasterRenderer pRasterRender = m_pRasterLayer.Renderer;
            if (pRasterRender is IRasterStretchColorRampRenderer)
            {
                m_rasterStretchColorRampRenderer = pRasterRender as IRasterStretchColorRampRenderer;
                cmbColorRamp.ColorScheme = m_rasterStretchColorRampRenderer.ColorScheme;

                #region 背景色
                IRasterStretch pRasterStretch = m_rasterStretchColorRampRenderer as IRasterStretch;
                if (pRasterStretch != null)
                {
                    if (pRasterStretch.Background)
                    {
                        cbkShowBack.Checked = true;
                        txtBkg.Enabled = true;
                        this.backgroundColor.Enabled = true;
                        txtBkg.Text = pRasterStretch.get_BackgroundValues().ToString("F0");
                        ESRI.ArcGIS.Display.IRgbColor pRGBcolor = pRasterStretch.BackgroundColor as ESRI.ArcGIS.Display.IRgbColor;
                        backgroundColor.SelectedColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.FromRGBColor(pRGBcolor);
                    }
                    else
                    {
                        cbkShowBack.Checked = false;
                        txtBkg.Enabled = false;
                        this.backgroundColor.Enabled = false;
                        txtBkg.Text = "0";
                    }
                }
                #endregion
                IRasterStretch3 pRasterStretch3 = m_rasterStretchColorRampRenderer as IRasterStretch3;
                this.cbxUseGammaStretch.Checked = pRasterStretch3.UseGamma;

                if (!pRasterStretch3.UseGamma)
                    this.txtGammaValue.Enabled = false;
                else
                    this.txtGammaValue.Text = pRasterStretch3.GammaValue.ToString();

                #region 山影
                IHillShadeInfo pHillShadeInfo = m_rasterStretchColorRampRenderer as IHillShadeInfo;
                if (pHillShadeInfo != null)
                {
                    cbkHillShadow.Checked = pHillShadeInfo.UseHillShade;
                    txtHillShadow.Enabled = pHillShadeInfo.UseHillShade;
                    txtHillShadow.Text = pHillShadeInfo.ZScale.ToString();
                }
                #endregion

                #region 无值象素显示颜色
                IRasterDisplayProps pRasterDisplayProps = m_rasterStretchColorRampRenderer as IRasterDisplayProps;
                if (pRasterDisplayProps != null)
                {
                    if (pRasterDisplayProps.NoDataColor.NullColor == false)
                    {
                        IRgbColor pRGBNocolor = pRasterDisplayProps.NoDataColor as ESRI.ArcGIS.Display.IRgbColor;
                        this.colorNoData.SelectedColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.FromRGBColor(pRGBNocolor);
                    }
                }
                #endregion

                #region 波段
                cbxBand.SelectedIndex = m_rasterStretchColorRampRenderer.BandIndex;//需要进行测试
                #endregion
            }
            else
            {
                m_rasterStretchColorRampRenderer = new RasterStretchColorRampRendererClass();
                pRasterRender = m_rasterStretchColorRampRenderer as IRasterRenderer;
                pRasterRender.Raster = m_pRasterLayer.Raster;
                pRasterRender.Update();
            }

            IRasterStretchMinMax pRasterStretchMinMax = m_rasterStretchColorRampRenderer as IRasterStretchMinMax;
            //lblMaxValue.Text = pRasterStretchMinMax.StretchMax.ToString("F0");
            //lblMinValue.Text = pRasterStretchMinMax.StretchMin.ToString("F0");

            txtMaxValueLable.Text = m_rasterStretchColorRampRenderer.LabelHigh;
            txtLabelMedium.Text = m_rasterStretchColorRampRenderer.LabelMedium;
            txtMinValueLabel.Text = m_rasterStretchColorRampRenderer.LabelLow;
            this.txtGammaValue.Enabled = this.cbxUseGammaStretch.Checked;
            #endregion
        }

        /// <summary>
        /// 初始化拉伸类型组合框
        /// </summary>
        private void InitStrechStyle()
        {
            if (m_pRasterLayer != null)
            {
                IRasterRenderer pRasterRender = m_pRasterLayer.Renderer;
                if (pRasterRender is IRasterStretchColorRampRenderer || pRasterRender is IRasterRGBRenderer)
                {
                    IRasterStretch pRasterStretch = pRasterRender as IRasterStretch;
                    if (pRasterStretch == null) return;
                    chkInvert.Checked = pRasterStretch.Invert;
                    if (pRasterStretch.StretchType == esriRasterStretchTypesEnum.esriRasterStretch_StandardDeviations)
                    {
                        txtDeviation.Text = pRasterStretch.StandardDeviationsParam.ToString();
                        txtDeviation.Enabled = true;
                    }
                    else
                    {
                        txtDeviation.Text = "";
                        txtDeviation.Enabled = false;
                    }
                    switch (pRasterStretch.StretchType)
                    {
                        case esriRasterStretchTypesEnum.esriRasterStretch_NONE:
                            this.cmbStrechStyle.SelectedIndex = 0;
                            break;
                        case esriRasterStretchTypesEnum.esriRasterStretch_Custom:
                            this.cmbStrechStyle.SelectedIndex = 1;
                            break;
                        case esriRasterStretchTypesEnum.esriRasterStretch_StandardDeviations:
                            this.cmbStrechStyle.SelectedIndex = 2;
                            break;
                        case esriRasterStretchTypesEnum.esriRasterStretch_HistogramEqualize:
                            this.cmbStrechStyle.SelectedIndex = 3;
                            break;
                        case esriRasterStretchTypesEnum.esriRasterStretch_MinimumMaximum:
                            this.cmbStrechStyle.SelectedIndex = 4;
                            break;
                        case esriRasterStretchTypesEnum.esriRasterStretch_HistogramSpecification:
                            this.cmbStrechStyle.SelectedIndex = 5;
                            break;
                        default:
                            this.cmbStrechStyle.SelectedIndex = 0;
                            break;
                    }
                }
                else
                {
                    cmbStrechStyle.SelectedIndex = 2;
                    txtDeviation.Text = "";
                    txtDeviation.Enabled = false;
                }
            }
        }
        
        /// <summary>
        /// 初始化波段列表
        /// </summary>
        private void InitBand()
        {
            if (m_pRasterLayer != null)
            {
                int iBandNum = m_pRasterLayer.BandCount;
                cbxBand.Items.Clear();
                for (int i = 1; i <= iBandNum; i++)
                {
                    cbxBand.Items.Add("Band_"+i.ToString());
                }
                if (cbxBand.Items.Count > 0) cbxBand.SelectedIndex = 0;
            }
        }
        

        /// <summary>
        /// 设置拉伸渲染
        /// </summary>
        public void SetStretchRenderer()
        {
            
            IRasterRenderer pRasterRender = m_rasterStretchColorRampRenderer as IRasterRenderer;
            pRasterRender.Raster = m_pRasterLayer.Raster;
            pRasterRender.Update();
            m_rasterStretchColorRampRenderer.ColorRamp = cmbColorRamp.SelectedColorRamp;
            m_rasterStretchColorRampRenderer.ColorScheme = cmbColorRamp.ColorScheme;
            m_rasterStretchColorRampRenderer.BandIndex = this.cbxBand.SelectedIndex ;           
            
            //m_rasterStretchColorRampRenderer.ResetLabels();

            IRasterStretch pRasterStretch = m_rasterStretchColorRampRenderer as IRasterStretch;

            if (pRasterStretch != null)
            {
                if (cbkShowBack.Checked)
                {
                    pRasterStretch.Background = true;
                    double pBkg = double.Parse(txtBkg.Text.ToString());
                    pRasterStretch.set_BackgroundValues(ref pBkg);
                    pRasterStretch.BackgroundColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(backgroundColor.SelectedColor) as IColor;
                }
                else
                {
                    pRasterStretch.Background = false;
                }

                pRasterStretch.Invert = chkInvert.Checked;

                if (cmbStrechStyle.SelectedText == "标准差方式拉伸")
                {
                    if (txtDeviation.Text.Trim() == "")
                        txtDeviation.Text = "1";
                    if (txtDeviation.Text == "0")
                        txtDeviation.Text = "1";
                    pRasterStretch.StandardDeviationsParam = Convert.ToDouble((string)txtDeviation.Text);
                }

                switch (this.cmbStrechStyle.Text)
                {
                    case "不拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_NONE;
                        break;
                    case "标准差方式拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_StandardDeviations;
                        break;
                    case "最大最小值方式拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_MinimumMaximum;
                        IRasterStretchMinMax rasterStretchMinMax = pRasterStretch as IRasterStretchMinMax;
                        rasterStretchMinMax.UseCustomStretchMinMax = true;

                        if (checkMinMaxValue() == true)
                        {
                            rasterStretchMinMax.CustomStretchMax = double.Parse(txtMaxValue.Text);
                            rasterStretchMinMax.CustomStretchMin = double.Parse(txtMinValue.Text);
                        }
                        else
                        {
                            rasterStretchMinMax.CustomStretchMax = 254;
                            rasterStretchMinMax.CustomStretchMin = 0;

                            resetMinMaxValue();
                        }

                        break;
                    case "自定义式拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_Custom;
                        
                        break;
                    case "直方图均衡法拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_HistogramEqualize;
                        break;
                    case "柱状图方式拉伸":
                        pRasterStretch.StretchType = esriRasterStretchTypesEnum.esriRasterStretch_HistogramSpecification;
                        break;
                }
                
                IRasterStretch3 pRasterStretch3 = m_rasterStretchColorRampRenderer as IRasterStretch3;

                switch (this.cmbStrechStyle.Text)
                {
                    case "不拉伸":
                    case "标准差方式拉伸":
                    case "最大最小值方式拉伸":                 
                        if (this.cbxUseGammaStretch.Checked)
                        {
                            pRasterStretch3.UseGamma = this.cbxUseGammaStretch.Checked;

                            try
                            {
                                //double[] dValue = (double[])pRasterStretch3.GammaValue;
                                //dValue[0] = double.Parse(this.txtGammaValue.Text.ToString());
                                pRasterStretch3.GammaValue = double.Parse(this.txtGammaValue.Text.ToString()); 
                            }
                            catch
                            {
                            }
                        }
                        else
                        {
                            pRasterStretch3.UseGamma = false;
                        }
                        break;
                    default:
                        pRasterStretch3.UseGamma = false;
                        break;
                }
            }

            IHillShadeInfo pHillShadeInfo= m_rasterStretchColorRampRenderer as IHillShadeInfo;

            if (pHillShadeInfo != null)
            {
                if (cbkHillShadow.Checked)
                {
                    pHillShadeInfo.UseHillShade = true;
                    if (txtHillShadow.Text.Trim() == "")
                        txtHillShadow.Text = "0.0001";                   
                    pHillShadeInfo.ZScale = double.Parse(txtHillShadow.Text.ToString());
                }
                else
                    pHillShadeInfo.UseHillShade = false;
            }

            IRasterDisplayProps pRasterDisplayProps = m_rasterStretchColorRampRenderer as IRasterDisplayProps;

            if (pRasterDisplayProps != null)
            {
                pRasterDisplayProps.NoDataColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(colorNoData.SelectedColor) as IColor;

                if (colorNoData.SelectedColor.Name == "ffedeada" || colorNoData.SelectedColor.Name == "Control")
                {
                    pRasterDisplayProps.NoDataColor.NullColor = true;
                    pRasterDisplayProps.TransparencyValue = 100;
                }
            }

            m_rasterStretchColorRampRenderer.LabelHigh = txtMaxValueLable.Text;
            m_rasterStretchColorRampRenderer.LabelMedium = txtLabelMedium.Text;
            m_rasterStretchColorRampRenderer.LabelLow = txtMinValueLabel.Text;

            this.m_pRasterLayer.Renderer = m_rasterStretchColorRampRenderer as IRasterRenderer;
            this.m_pRasterLayer.Renderer.Update();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkHillShadow_CheckedChanged(object sender, EventArgs e)
        {
            txtHillShadow.Enabled = cbkHillShadow.Checked;
            txtHillShadow.Text = "1";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chkShowBack_CheckedChanged(object sender, EventArgs e)
        {
            txtBkg.Enabled = cbkShowBack.Checked;
            txtBkg.Text = "0";
            backgroundColor.Enabled = cbkShowBack.Checked;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbStrechStyle_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbStrechStyle.Text == "标准差方式拉伸")
            {
                txtDeviation.Enabled = true;
                lblDevation.Enabled = true;
            }
            else
            {
                txtDeviation.Enabled = false;
                lblDevation.Enabled = false;
            }

            if (cmbStrechStyle.Text == "最大最小值方式拉伸")
            {
                IRasterStretch pRasterStretch = m_rasterStretchColorRampRenderer as IRasterStretch;
                IRasterStretchMinMax rasterStretchMinMax = pRasterStretch as IRasterStretchMinMax;
                txtMaxValue.Text = rasterStretchMinMax.StretchMax.ToString();
                txtMinValue.Text = rasterStretchMinMax.StretchMin.ToString();
                txtMaxValue.Show();
                txtMinValue.Show();
            }
            else
            {
                txtMaxValue.Hide();
                txtMinValue.Hide(); ;
            }

            switch (this.cmbStrechStyle.Text)
            {
                case "不拉伸":
                case "标准差方式拉伸":
                case "最大最小值方式拉伸":
                    this.cbxUseGammaStretch.Show();
                    this.txtGammaValue.Show();
                    break;
                case "自定义式拉伸":
                case "直方图均衡法拉伸":
                case "柱状图方式拉伸":
                    this.cbxUseGammaStretch.Hide();
                    this.txtGammaValue.Hide();
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbxUseGammaStretch_CheckedChanged(object sender, EventArgs e)
        {
            this.txtGammaValue.Enabled = this.cbxUseGammaStretch.Checked;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtBkg_TextChanged(object sender, EventArgs e)
        {
            if ( isNumber(txtBkg.Text) == false )
            {
                txtBkg.Text = "0";
            }
        }

        /// <summary>
        /// 判断字符串是否为数字
        /// added by xhb 20110308
        /// </summary>
        /// <param name="pString"></param>
        /// <returns></returns>
        private bool isNumber(string pString)
        {
            pString = pString.Trim();
            if (!VerifyHelper.IsNumber(pString) && !pString.Equals('.')) 
            {
                MsgHelper.ShowWarningMsgbox("请输入数字！");
                return false;
            }

            //foreach ( char charTemp in pString )
            //{
            //    if ( charTemp != '0' &&
            //         charTemp != '1' &&
            //         charTemp != '2' &&
            //         charTemp != '3' &&
            //         charTemp != '4' &&
            //         charTemp != '5' &&
            //         charTemp != '6' &&
            //         charTemp != '7' &&
            //         charTemp != '8' &&
            //         charTemp != '9' )
            //    {
            //        MessageBox.Show("请输入数字！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

            //        return false;
            //    }
            //}
            return true;
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtHillShadow_TextChanged(object sender, EventArgs e)
        {
            if (isNumber(txtHillShadow.Text) == false)
            {
                txtHillShadow.Text = "1";
            }
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtGammaValue_TextChanged(object sender, EventArgs e)
        {
            if (isNumber(txtGammaValue.Text) == false)
            {
                txtGammaValue.Text = "1";
            }
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtDeviation_TextChanged(object sender, EventArgs e)
        {
            if (isNumber(txtDeviation.Text) == false)
            {
                txtDeviation.Text = "2";
            }
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtMaxValue_TextChanged(object sender, EventArgs e)
        {
            if (isNumber(txtMaxValue.Text) == false)
            {
                txtMaxValue.Text = "255";
            }

            txtMaxValueLable.Text = "High : " + txtMaxValue.Text;
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtMinValue_TextChanged(object sender, EventArgs e)
        {
            if (isNumber(txtMinValue.Text) == false)
            {
                txtMinValue.Text = "0";
            }

            txtMinValueLabel.Text = "Low : " + txtMinValue.Text;
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private bool checkMinMaxValue()
        {
            if (txtMaxValue.Text.Trim() == "" || txtMinValue.Text.Trim() == "")
            {
                return false;
            }

            if (double.Parse(txtMaxValue.Text.Trim()) <= double.Parse(txtMinValue.Text.Trim()))
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// added by xhb 20110308
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void resetMinMaxValue()
        {
            txtMaxValue.Text = "254";
            txtMinValue.Text = "0";
        }
    }
}
